package com.witframework.web.filter;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ajaxanywhere.BufferResponseWrapper;
import org.ajaxanywhere.PreSendHandler;
import org.ajaxanywhere.XMLHandler;

import com.witframework.WitException;
import com.witframework.web.ajax.WsAAUtils;

public class WsAAFilter implements Filter {

    public String preSendHandlerClassName;

    public void init(FilterConfig filterConfig) throws ServletException {
        preSendHandlerClassName = filterConfig.getInitParameter("preSendHandlerClass");
    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        
        if (!WsAAUtils.isAjaxRequest(servletRequest)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/xml;charset=utf-8");

        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setHeader("Pragma", "no-cache");

        BufferResponseWrapper bufferResponseWrapper = new BufferResponseWrapper(response);

        Set refreshZones = new HashSet();
        WsAAUtils.setZonesToRefresh(request, refreshZones);
        WsAAUtils.getRefreshZonesFromURL(request);
        try {
            filterChain.doFilter(request, bufferResponseWrapper);

            bufferResponseWrapper = execHandler(request,bufferResponseWrapper);

            if (bufferResponseWrapper.getRedirect() != null) {
                XMLHandler.sendRedirect(bufferResponseWrapper);
            } else {
                XMLHandler.sendZones(bufferResponseWrapper, refreshZones);
            }
        }

        catch (Throwable e) {
        	if(e instanceof WitException ||e instanceof RuntimeException ){
        		throw new WitException(e);
        	}        	
            XMLHandler.handleError(response, e);
        }

    }

    private BufferResponseWrapper execHandler(HttpServletRequest request, BufferResponseWrapper bufferResponseWrapper) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        if (preSendHandlerClassName!=null){
            Class hClass;
            try {
                hClass = Thread.currentThread().getContextClassLoader().loadClass(preSendHandlerClassName);
            } catch (ClassNotFoundException e) {
                hClass = Class.forName(preSendHandlerClassName);
                e.printStackTrace();
            }
            PreSendHandler handler = (PreSendHandler) hClass.newInstance();
            return handler.handle(request, bufferResponseWrapper);
        }
        return bufferResponseWrapper;
    }

    public void destroy() {
    	preSendHandlerClassName=null;
    }
}
